import imageCompression from 'browser-image-compression';

// Image loading states and cache
const imageCache = new Map<string, Promise<string>>();
const loadedImages = new Set<string>();
const imageLoadQueue = new Set<string>();
const CONCURRENT_LOADS = 3;

// Lazy loading observer
let lazyLoadObserver: IntersectionObserver | null = null;
const lazyLoadCallbacks = new Map<string, () => void>();

// Initialize lazy loading observer
function initLazyLoadObserver() {
  if (!lazyLoadObserver && 'IntersectionObserver' in window) {
    lazyLoadObserver = new IntersectionObserver((entries) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          const callback = lazyLoadCallbacks.get(entry.target.getAttribute('data-src') || '');
          if (callback) {
            callback();
            lazyLoadCallbacks.delete(entry.target.getAttribute('data-src') || '');
            lazyLoadObserver?.unobserve(entry.target);
          }
        }
      });
    }, {
      rootMargin: '50px 0px',
      threshold: 0.1
    });
  }
}

export async function compressImage(file: File): Promise<string> {
  const options = {
    maxSizeMB: 0.3,
    maxWidthOrHeight: 1600,
    useWebWorker: true,
    initialQuality: 0.7
  };

  try {
    const compressedFile = await imageCompression(file, options);
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.onload = (e) => resolve(e.target?.result as string);
      reader.onerror = (e) => reject(e);
      reader.readAsDataURL(compressedFile);
    });
  } catch (error) {
    console.error('图片压缩失败:', error);
    throw new Error('图片压缩失败，请重试');
  }
}

// Load images in queue
async function processImageQueue() {
  if (imageLoadQueue.size === 0) return;

  const loading = new Set<Promise<void>>();
  for (const url of imageLoadQueue) {
    if (loading.size >= CONCURRENT_LOADS) {
      await Promise.race(loading);
    }

    const loadPromise = (async () => {
      try {
        const img = new Image();
        const promise = new Promise<void>((resolve, reject) => {
          img.onload = () => {
            loadedImages.add(url);
            imageLoadQueue.delete(url);
            resolve();
          };
          img.onerror = reject;
        });
        img.src = url;
        await promise;
      } catch (error) {
        console.error(`Failed to load image: ${url}`, error);
        imageLoadQueue.delete(url);
      }
    })();

    loading.add(loadPromise);
    loadPromise.then(() => loading.delete(loadPromise));
  }

  await Promise.all(loading);
}

// Preload image with priority
export function preloadImage(url: string, priority: boolean = false): Promise<string> {
  if (loadedImages.has(url)) {
    return Promise.resolve(url);
  }

  if (imageCache.has(url)) {
    return imageCache.get(url)!;
  }

  const promise = new Promise<string>((resolve) => {
    if (priority) {
      const img = new Image();
      img.onload = () => {
        loadedImages.add(url);
        resolve(url);
      };
      img.src = url;
    } else {
      imageLoadQueue.add(url);
      processImageQueue().then(() => resolve(url));
    }
  });

  imageCache.set(url, promise);
  return promise;
}

// Register element for lazy loading
export function registerLazyLoad(element: HTMLElement, url: string, callback: () => void) {
  if (!lazyLoadObserver) {
    initLazyLoadObserver();
  }
  
  element.setAttribute('data-src', url);
  lazyLoadCallbacks.set(url, callback);
  lazyLoadObserver?.observe(element);
}

export function calculateStorageUsage(): number {
  let total = 0;
  for (let i = 0; i < localStorage.length; i++) {
    const key = localStorage.key(i);
    if (key) {
      total += localStorage.getItem(key)?.length || 0;
    }
  }
  return total / (1024 * 1024);
}

export const MAX_STORAGE_MB = 10;